package com.example.administrator.base.util;

import android.util.Log;

/**
 * Created by Erebus on 2017/3/10.
 */

public class BleMessageUtil {
    public static final String TAG = "BleMessageUtil";
    public static final String UUID_KEY_DATA_S = "0000ffe0-0000-1000-8000-00805f9b34fb";
    public static final String UUID_KEY_DATA_C = "0000ffe1-0000-1000-8000-00805f9b34fb";
    private static final String DATA_HEAD = "40";//包头
    private static final String DATA_END = "0D0A";//包尾
    private static final int DATA_LENGTH = 20;//数据长度
    public static final int DATA_DEVICE_BATTERY = 1;//车锁的设备 电池锁
    public static final int DATA_DEVICE_CLOCK = 0; //开锁的设备 车锁
    private static final int DATA_USER_TYPE = 0;//用户类型 此APP 为0
    private static final int DATA_RESERVE = 0;//预留

    //0：开锁成功 1：开锁失败 2：车锁未关闭 3：电池所未关闭 4：车上无电池 5.设备故障
    public static final int UNLOCK_RESULT_OK = 0;
    public static final int UNLOCK_RESULT_OPEN_FAILURE = 1;
    public static final int UNLOCK_RESULT_BICYCLE_LOCK_NOT_CLOSE = 2;
    public static final int UNLOCK_RESULT_BATTERY_LOCK_NOT_CLOSE = 3;
    public static final int UNLOCK_RESULT_NO_BATTERY = 4;
    public static final int UNLOCK_RESULT_DEVICE_ERROR = 5;

    //锁状态 0 锁开 1 锁关 2 锁坏
    public static final int STATE_LOCK_ON = 0;
    public static final int STATE_LOCK_OFF = 1;
    public static final int STATE_LOCK_FAILURE = 2;

    public static final int STATE_CONTROLLER_NOT_WORKING = 0;
    public static final int STATE_CONTROLLER_WORKING = 1;

    //电池状态 0 不在车上 1 在车上
    public static final int STATE_BATTERY_NOT_IN_BICYCLE = 0;
    public static final int STATE_BATTERY_IN_BICYCLE = 1;

    public static final int WORKING_INSTRUCT_OPEN_LOCK = 7; //开锁指令
    public static final int WORKING_INSTRUCT_GET_STATUS = 8;//获取设备状态信息指令


    /**
     * 获取锁设备状态
     *
     * @return 蓝牙发送所需的字节数组
     */
    public static byte[] getDriveStatus() {
        return BLEStringUtils.HexString2Bytes(getFinalData(setData(new StringBuilder())));
    }

    /**
     * 开车锁
     *
     * @param orderNum 订单号
     * @return 蓝牙发送所需的字节数组
     */
    public static byte[] openClockByDrive(long orderNum) {
        return BLEStringUtils.HexString2Bytes(getFinalData(setBikeNum(setDevice(new StringBuilder(), DATA_DEVICE_CLOCK), orderNum)));
    }

    /**
     * 开电频锁
     *
     * @param orderNum 订单号
     * @return 蓝牙发送所需的字节数组
     */
    public static byte[] openClockByChangeBat(long orderNum) {
        return BLEStringUtils.HexString2Bytes(getFinalData(setBikeNum(setDevice(new StringBuilder(), DATA_DEVICE_BATTERY), orderNum)));
    }

    /**
     * 设置开锁的设备
     *
     * @param builder 字符串流
     * @param device  设备
     * @return 用于拼接的字符串流
     */
    private static StringBuilder setDevice(StringBuilder builder, int device) {
        return builder.append(BLEStringUtils.numToHex(DATA_LENGTH, 1))
                .append(BLEStringUtils.numToHex(WORKING_INSTRUCT_OPEN_LOCK, 1))
                .append(BLEStringUtils.numToHex(device, 1));
    }

    private static StringBuilder setData(StringBuilder builder) {
        return builder.append(BLEStringUtils.numToHex(DATA_LENGTH, 1))
                .append(BLEStringUtils.numToHex(WORKING_INSTRUCT_GET_STATUS, 1))
                .append(BLEStringUtils.numToHex(DATA_RESERVE, 13));
    }

    /**
     * 设置开锁的车号
     *
     * @param builder 字符串流
     * @param bikeNum 车号
     * @return 用于拼接的字符串流
     */
    private static StringBuilder setBikeNum(StringBuilder builder, long bikeNum) {
        return builder.append(BLEStringUtils.numToHex(bikeNum, 6))
                .append(BLEStringUtils.numToHex(DATA_USER_TYPE, 1))
                .append(BLEStringUtils.numToHex(DATA_RESERVE, 5));
    }

    /**
     * 获取拼接完成后的字符串
     *
     * @param builder 字符串流
     * @return 拼接完成后的字符串
     */
    private static String getFinalData(StringBuilder builder) {
        int crc16 = BLEStringUtils.calcCrc16(BLEStringUtils.HexString2Bytes(builder.toString()));
        builder.append(BLEStringUtils.numToHex(crc16, 2));
        builder.insert(0, DATA_HEAD);
        builder.append(DATA_END);
        return builder.toString().toUpperCase();
    }

    /**
     * 数据验证
     *
     * @param data 原始数据
     * @return true 验证通过 false 验证失败
     */
    public static boolean dataValidation(String data) {
        if (data.length() != 40) {
            Log.d(TAG, "数据长度异常");
            return false;
        }
        if (!data.startsWith("24")) {
            Log.d(TAG, "包头不正确");
            return false;
        }
        if (!data.endsWith(DATA_END)) {
            Log.d(TAG, "包尾不正确");
            return false;
        }
        String crc16 = BLEStringUtils.numToHex(BLEStringUtils.
                calcCrc16(BLEStringUtils.HexString2Bytes(
                        data.substring(2, data.length() - (4 + DATA_END.length())))), 2);
        if (!crc16.equalsIgnoreCase(data.substring(data.length() - (4 + DATA_END.length()), data.length() - DATA_END.length()))) {
            Log.d(TAG, "crc16验证不正确");
            return false;
        }
        return true;
    }

    /**
     * 得到开锁结果
     *
     * @param data 原始数据
     * @return 0：开锁成功 1：开锁失败 2：车锁未关闭 3：电池所未关闭 4：车上无电池 5:设备故障
     */
    public static int unlockResults(String data) {
        return Integer.parseInt(data.substring(8, 10), 16);
    }


    /**
     * 获取车锁状态
     *
     * @param data 原始数据
     * @return 0 锁开 1 锁关 2 锁坏
     */
    public static int getBicycleLockState(String data) {
        return Integer.parseInt(data.substring(6, 8), 16);
    }

    /**
     * 获取电池锁状态
     *
     * @param data 原始数据
     * @return 0 锁开 1 锁关 2 锁坏
     */
    public static int getBatteryLockState(String data) {
        return Integer.parseInt(data.substring(18, 20), 16);
    }

    /**
     * 获取电池状态
     *
     * @param data 原始数据
     * @return 0 电池不在车上   1 电池在车上
     */
    public static int getBatteryState(String data) {
        return Integer.parseInt(data.substring(20, 22), 16);
    }

    /**
     * 获取控制器状态
     *
     * @param data 原始数据
     * @return 0 控制器断电    1 控制器通电
     */
    public static int getControllerState(String data) {
        return Integer.parseInt(data.substring(8, 10), 16);
    }


    /**
     * @param data 原始数据
     * @return int[0]:车锁状态 int[1]:控制器状态 int[2]:电池锁状态 int[3]:电池状态
     */
    private static int[] bicycleStateResults(String data) {
        int[] results = {
                Integer.parseInt(data.substring(6, 8), 16),
                Integer.parseInt(data.substring(8, 10), 16),
                Integer.parseInt(data.substring(18, 20), 16),
                Integer.parseInt(data.substring(20, 22), 16),
        };
        return results;
    }

    /**
     * 获取当前蓝牙反馈指令 7开锁反馈 8查询设备状态反馈
     * @param data 反馈的原始数据
     * @return  7 开锁 8 设备信息
     */
    public static int getWorkingInstruct(String data) {
        return Integer.parseInt(data.substring(4, 6), 16);
    }
}
